grammar CSV;

@parser::header {
package org.churchillroadpta.csvparser;
}

@lexer::header {
package org.churchillroadpta.csvparser;
}

@lexer::members {
List<RecognitionException> exceptions = new ArrayList<RecognitionException>();

public List<RecognitionException> getExceptions() {
	return exceptions;
}

@Override
public void reportError(RecognitionException e) {
	super.reportError(e);
	exceptions.add(e);
}
}

csvfile returns [List results]
scope {List lines;}
@init {$csvfile::lines = new ArrayList();}
@after {$results = $csvfile::lines;}
	:	line*
	;
	
line
scope {List fields;}
@init {$line::fields = new ArrayList();}
	: 	(
		(NEWLINE) => NEWLINE
		| field(COMMA field)* NEWLINE
		)
		{ $csvfile::lines.add($line::fields); }
  	;
	  	
field 
	:	(f=QUOTED
		|f=UNQUOTED
		| // nothing
		)
		{$line::fields.add(($f == null) ? "" : $f.text);}
	;
	
NEWLINE	:	'\r'? '\n';

COMMA	: 	(' '* ',' ' '*);

QUOTED	: ('"' (options{greedy=false;}: .)+ '"')+
		{
			StringBuilder txt = new StringBuilder(getText());
			// Remove first and last double-quote
			txt.deleteCharAt(0);
			txt.deleteCharAt(txt.length()-1);
			// "" -> "
			int probe;
			while ((probe = txt.lastIndexOf("\"\"")) >= 0) {
				txt.deleteCharAt(probe);
			}
			setText(txt.toString());
		};

UNQUOTED
	:	~('\r' | '\n' | ',' | '"')+;
